package com.motu.vertx.module.utility.toolset;

import com.aliyun.TextAutoRoute;
import com.aliyun.TextCheckException;
import com.aliyun.TextCheckResult;
import com.mchange.io.FileUtils;
import com.motu.vertx.module.utility.mysql.MysqlClient;
import com.motu.vertx.module.utility.mysql.MysqlTool;
import com.other.api.XingyouTool;
import com.wx.v3.WxTool;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.WebClient;
import io.vertx.redis.client.RedisAPI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 敏感词过滤工具类
 */
public class SensitivewordEngine {
	private static final Logger logger = LoggerFactory.getLogger(SensitivewordEngine.class);
	/**
	 * 敏感词库
	 */
	public static Map sensitiveWordMap = null;

	/**
	 * 只过滤最小敏感词
	 */
	public static final int MinMatchType = 1;

	/**
	 * 过滤所有敏感词
	 */
	public static final int MaxMatchType = 2;

	public static void init() {
		if (MysqlClient.getBadwordPool() == null) {
			return;
		}
		logger.info("badwords init start...");
		long startTime = System.currentTimeMillis();
		String sql = "select word from badwords;";
		MysqlTool.queryJsonArrayFromDb(MysqlClient.getBadwordPool(), sql, new JsonArray(), handler -> {
			if (handler.succeeded()) {
				JsonArray list = handler.result();
				List<String> sensitiveWords = new ArrayList<String>();
				for (int i = 0; i < list.size(); i++) {
					JsonObject obj = list.getJsonObject(i);
					String word = obj.getString("word").toLowerCase();
					sensitiveWords.add(word);
				}
				SensitiveWordInit sensitiveWordInit = new SensitiveWordInit();
				Map sensitiveWordMap = sensitiveWordInit.initKeyWord(sensitiveWords);
				// 传入SensitivewordEngine类中的敏感词库
				SensitivewordEngine.sensitiveWordMap = sensitiveWordMap;
				logger.info("badwords init size:" + list.size() + " runTime:" + (System.currentTimeMillis() - startTime) + "ms");
			} else {
				logger.error("badwords init failed! reason:" + handler.cause().getMessage() + " runTime:" + (System.currentTimeMillis() - startTime) + "ms");
			}
		});
	}

	/**
	 * 敏感词库敏感词数量
	 *
	 * @return
	 */
	public static int getWordSize() {
		if (SensitivewordEngine.sensitiveWordMap == null) {
			return 0;
		}
		return SensitivewordEngine.sensitiveWordMap.size();
	}

	/**
	 * 是否包含敏感词
	 *
	 * @param txt
	 * @param matchType
	 * @return
	 */
	public static boolean isContaintSensitiveWord(String txt, int matchType) {
		boolean flag = false;
		for (int i = 0; i < txt.length(); i++) {
			int matchFlag = checkSensitiveWord(txt, i, matchType);
			if (matchFlag > 0) {
				flag = true;
			}
		}
		return flag;
	}

	/**
	 * 获取敏感词内容
	 *
	 * @param txt
	 * @param matchType
	 * @return 敏感词内容
	 */
	public static Set<String> getSensitiveWord(String txt, int matchType) {
		Set<String> sensitiveWordList = new HashSet<String>();

		for (int i = 0; i < txt.length(); i++) {
			int length = checkSensitiveWord(txt, i, matchType);
			if (length > 0) {
				// 将检测出的敏感词保存到集合中
				sensitiveWordList.add(txt.substring(i, i + length));
				i = i + length - 1;
			}
		}

		return sensitiveWordList;
	}

	/**
	 * 第三方sdk替换敏感词（只针对取名检测使用，因为检测有QPS限制，所以取名单独使用一个账号）
	 */
	public static String replaceNameBySdk(String msg, int platform) throws Exception {
		return replaceBySdk(msg, platform, 1);
	}

	/**
	 * 第三方sdk替换敏感词（除了取名之外的文字检测，例如聊天等）
	 */
	public static String replaceWordBySdk(String msg, int platform) throws Exception {
		return replaceBySdk(msg, platform, 2);
	}

	/**
	 * 第三方sdk替换敏感词
	 */
	private static String replaceBySdk(String msg, int platform, int type) throws Exception {
		if (Tool.isEmpty(msg)) {
			return msg;
		}
		if (SensitivewordEngine.isDecorateContent(msg)) {
			// 富文本直接抛异常
			throw new TextCheckException();
		}
		if (platform < 3000) {
			// 国内渠道调用第三方sdk屏蔽字验证
			if (Tool.isContainChinese(msg) || Tool.isContainLetter(msg)) {
				// 有包含中文或字母才需要第三方校验（表情或者纯数字等可以不用第三方校验）
				TextCheckResult textCheckResult;
				if (type == 1) {
					textCheckResult = TextAutoRoute.checkName(msg);
				} else {
					textCheckResult = TextAutoRoute.checkWord(msg);
				}
				if (textCheckResult.isPass()) {
					// 第三方验证过后再经过自己的屏蔽字库验证
					msg = SensitivewordEngine.replaceSensitiveWord(msg, SensitivewordEngine.MaxMatchType, "*");
				} else {
					// 第三方验证不过
					if (Tool.isEmpty(textCheckResult.getFilteredContent())) {
						// 如果没有返回过滤字符，则返回给客户端错误码
						throw new TextCheckException();
					} else {
						// 如果有返回过滤字符，则把过滤字符下发给客户端
						msg = textCheckResult.getFilteredContent();
					}
				}
			} else {
				// 没有包含中文或字母则直接用自己的屏蔽字库验证
				msg = SensitivewordEngine.replaceSensitiveWord(msg, SensitivewordEngine.MaxMatchType, "*");
			}
		} else {
			// 非国内渠道只需要调用自己的屏蔽字库进行验证
			msg = SensitivewordEngine.replaceSensitiveWord(msg, SensitivewordEngine.MaxMatchType, "*");
		}
		return msg;
	}

	/**
	 * 微信小游戏替换敏感词
	 */
	public static void replaceByWechatGame(WebClient webClient, RedisAPI redisClient, String WX_MINIGAME_APPID, String WECHAT_GAME_LOGIN_KEY, String WX_MINIGAME_ACCESSTOKEN_HTTP, String openId, String msg, Handler<AsyncResult<String>> onComplete) {
		if (Tool.isEmpty(msg)) {
			onComplete.handle(Future.succeededFuture(msg));
			return;
		}
		if (SensitivewordEngine.isDecorateContent(msg)) {
			// 富文本直接抛异常
			onComplete.handle(Future.failedFuture("包含富文本"));
			return;
		}
		if (Tool.isEmpty(openId)) {
			// 如果不是用微信登录，取不到openid，则用自己的屏蔽字库验证
			msg = SensitivewordEngine.replaceSensitiveWord(msg, SensitivewordEngine.MaxMatchType, "*");
			onComplete.handle(Future.succeededFuture(msg));
			return;
		}
		if (Tool.isContainChinese(msg) || Tool.isContainLetter(msg)) {
			// 有包含中文或字母才需要第三方校验（表情或者纯数字等可以不用第三方校验）
			Future<Boolean> checkResult = WxTool.msgSecCheck(webClient, redisClient, WX_MINIGAME_APPID, WECHAT_GAME_LOGIN_KEY, WX_MINIGAME_ACCESSTOKEN_HTTP, openId, msg);
			String finalMsg = msg;
			checkResult.onComplete(res -> {
				if (res.result()) {
					// 第三方验证过后再经过自己的屏蔽字库验证
					String resultMsg = SensitivewordEngine.replaceSensitiveWord(finalMsg, SensitivewordEngine.MaxMatchType, "*");
					onComplete.handle(Future.succeededFuture(resultMsg));
				} else {
					onComplete.handle(Future.failedFuture("验证失败"));
				}
			});
		} else {
			// 没有包含中文或字母则直接用自己的屏蔽字库验证
			msg = SensitivewordEngine.replaceSensitiveWord(msg, SensitivewordEngine.MaxMatchType, "*");
			onComplete.handle(Future.succeededFuture(msg));
		}
	}


	public static void replaceByXingyouWechatGame(WebClient webClient, int cchid, int appid, String xingyouKey, String openId, String msg, Handler<AsyncResult<String>> onComplete) {
		if (Tool.isEmpty(msg)) {
			onComplete.handle(Future.succeededFuture(msg));
			return;
		}
		if (SensitivewordEngine.isDecorateContent(msg)) {
			// 富文本直接抛异常
			onComplete.handle(Future.failedFuture("包含富文本"));
			return;
		}
		if (Tool.isEmpty(openId)) {
			// 如果不是用微信登录，取不到openid，则用自己的屏蔽字库验证
			msg = SensitivewordEngine.replaceSensitiveWord(msg, SensitivewordEngine.MaxMatchType, "*");
			onComplete.handle(Future.succeededFuture(msg));
			return;
		}
		if (Tool.isContainChinese(msg) || Tool.isContainLetter(msg)) {
			// 有包含中文或字母才需要第三方校验（表情或者纯数字等可以不用第三方校验）
			Future<Boolean> checkResult = XingyouTool.wxMsgSecCheck(webClient, cchid, appid, xingyouKey, openId, msg);
			String finalMsg = msg;
			checkResult.onComplete(res -> {
				if (res.result()) {
					// 第三方验证过后再经过自己的屏蔽字库验证
					String resultMsg = SensitivewordEngine.replaceSensitiveWord(finalMsg, SensitivewordEngine.MaxMatchType, "*");
					onComplete.handle(Future.succeededFuture(resultMsg));
				} else {
					onComplete.handle(Future.failedFuture("验证失败"));
				}
			});
		} else {
			// 没有包含中文或字母则直接用自己的屏蔽字库验证
			msg = SensitivewordEngine.replaceSensitiveWord(msg, SensitivewordEngine.MaxMatchType, "*");
			onComplete.handle(Future.succeededFuture(msg));
		}
	}

	/**
	 * 替换敏感词
	 *
	 * @param txt
	 * @param matchType
	 * @param replaceChar
	 * @return
	 */
	public static String replaceSensitiveWord(String txt, int matchType, String replaceChar) {
		String resultTxt = txt;
		// 过滤地下城表情
		resultTxt = resultTxt.replaceAll("\\{([0-9][0-9])}", "");
		// 过滤标点符号回车换行
		resultTxt = resultTxt.replaceAll("[\\pP\\p{Punct}]", "");
		// 过滤非字母数字但除了各国文字、带圈的字符
		resultTxt = resultTxt.replaceAll("[^a-zA-Z0-9\\p{L}+\\p{N}\\u2460-\\u24FF\\u24B6-\\u24EA]", "");
		// 大写字母的下标
		List<Integer> upperCaseIndexList = getUpperCaseIndexList(resultTxt);
		// 统统设置为小写
		resultTxt = resultTxt.toLowerCase();
		Set<String> set = getSensitiveWord(resultTxt, matchType);
		String filtedContent = txt;
		if (!set.isEmpty()) {
			// 记住位置
			List<Character> contentList = splitContent(txt);
			Iterator<String> iterator = set.iterator();
			String word = null;
			String replaceString = null;
			while (iterator.hasNext()) {
				word = iterator.next();
				replaceString = getReplaceChars(replaceChar, word.length());
				resultTxt = resultTxt.replaceAll("\\+", "");// +是正则中的特殊字符，加上这句可以解决文字中包含+不会被替换的问题
				resultTxt = resultTxt.replaceAll(word, replaceString);
			}
			// 还原位置
			List<Character> replacedContentList = getContentCharList(resultTxt);
			int index = 0;
			for (int i = 0; i < contentList.size(); i++) {
				if (contentList.get(i) == null) {
					if (index > replacedContentList.size() - 1) {
						// 防止过滤失败造成服务端越界
						return txt;
					}
					char b = replacedContentList.get(index);
					if (upperCaseIndexList.contains(index)) {
						contentList.set(i, Character.toUpperCase(b));
					} else {
						contentList.set(i, b);
					}
					index++;
				}
			}
			StringBuilder stringBuilder = new StringBuilder();
			for (Character character : contentList) {
				stringBuilder.append(character);
			}
			filtedContent = stringBuilder.toString();
		}
		// 把经过字符特殊过滤的进行一遍无字符过滤的条件进行屏蔽字过滤
		return replaceSensitiveWord2(filtedContent, matchType, replaceChar);
	}

	private static String replaceSensitiveWord2(String txt, int matchType, String replaceChar) {
		String resultTxt = txt;
		// 去除空格
		resultTxt = resultTxt.replaceAll(" ", "");
		Set<String> set = getSensitiveWord(resultTxt, matchType);
		if (!set.isEmpty()) {
			// 记住位置
			char[] array = txt.toCharArray();
			List<Character> contentList = new ArrayList<>();
			for (char c : array) {
				if (!Character.isSpaceChar(c)) {
					contentList.add(null);
				} else {
					contentList.add(c);
				}
			}
			Iterator<String> iterator = set.iterator();
			String word = null;
			String replaceString = null;
			while (iterator.hasNext()) {
				word = iterator.next();
				replaceString = getReplaceChars(replaceChar, word.length());
				resultTxt = resultTxt.replaceAll("\\+", "");// +是正则中的特殊字符，加上这句可以解决文字中包含+不会被替换的问题
				resultTxt = resultTxt.replaceAll(word, replaceString);
			}
			// 还原位置
			List<Character> replacedContentList = getContentCharList(resultTxt);
			int index = 0;
			for (int i = 0; i < contentList.size(); i++) {
				if (contentList.get(i) == null) {
					char b = replacedContentList.get(index);
					contentList.set(i, b);
					index++;
				}
			}
			StringBuilder stringBuilder = new StringBuilder();
			for (Character character : contentList) {
				stringBuilder.append(character);
			}
			return stringBuilder.toString();
		}
		return txt;
	}

	/**
	 * 是否是富文本
	 *
	 * @param str
	 * @return
	 */
	public static boolean isDecorateContent(String str) {
		boolean first = false;
		for (int i = 0; i < str.length(); i++) {
			if (str.charAt(i) == '{') {
				// 找到 { 后开始查找 =
				for (int j = i + 1; j < str.length(); j++) {
					if (str.charAt(j) == '=') {
						first = true;
					} else if (!first && str.charAt(j) == '}') {
						break; // 没有 = 就到 } 提前跳出往后继续找
					} else if (first && str.charAt(j) == '}') {
						return true; // 有包含 {=}
					}
				}
			}
		}
		return false;
	}

	/**
	 * 拆分文本内容
	 *
	 * @param content
	 * @return
	 */
	public static List<Character> splitContent(String content) {
		char[] array = content.toCharArray();
		List<Character> contentList = new ArrayList<>();
		for (int i = 0; i < array.length; i++) {
			char c = array[i];
			if (isCircleCharacter(c)) {
				contentList.add(null);
			} else if (Character.isLetterOrDigit(c)) {
				// 过滤地下城表情 {01}-{99}
				if (i > 0 && array[i - 1] == '{'
						&& i + 2 <= array.length - 1 && array[i + 2] == '}') {
					contentList.add(c);
				} else if (i > 1 && array[i - 2] == '{'
						&& i + 1 <= array.length - 1 && array[i + 1] == '}') {
					contentList.add(c);
				} else {
					contentList.add(null);
				}
			} else {
				contentList.add(c);
			}
		}
		return contentList;
	}

	public static boolean isCircleCharacter(char c) {
		// 判断字符是否为带圈字符
		return (c >= '\u2460' && c <= '\u24FF') || (c >= '\u24B6' && c <= '\u24EA');
	}

	/**
	 * 返回大写的下标集合
	 *
	 * @param content
	 * @return
	 */
	public static List<Integer> getUpperCaseIndexList(String content) {
		char[] array = content.toCharArray();
		List<Integer> indexList = new ArrayList<>();
		for (int i = 0; i < array.length; i++) {
			if (Character.isUpperCase(array[i])) {
				indexList.add(i);
			}
		}
		return indexList;
	}

	public static List<Character> getContentCharList(String content) {
		char[] array = content.toCharArray();
		List<Character> contentList = new ArrayList<>();
		for (char c : array) {
			contentList.add(c);
		}
		return contentList;
	}

	/**
	 * 替换敏感词（排除表情）
	 */
	public static String replaceSensitiveWordExcludeFace(String txt, int matchType, String replaceChar) {
		int index = 0;
		int count = txt.length();// 最多检查次数
		List<String> faceList = new ArrayList<>();// 文本中包含的表情符,例如 01
		List<String> faceReplaceList = new ArrayList<>();// 文本中包含的表情符,例如{01}

		// 检查文本中是否包含表情符
		while (index < txt.length() && count >= 0) {
			count--;
			int startIndex = txt.indexOf("{", index);
			int nextStartIndex = txt.indexOf("{", index + 1);
			int endIndex = txt.indexOf("}", index);
			if (startIndex == -1 || endIndex == -1) {
				break;
			}
			if (startIndex > endIndex) {
				index = startIndex;
				continue;
			}
			if (nextStartIndex != -1 && nextStartIndex < endIndex) {
				index = nextStartIndex;
				continue;
			}
			index = endIndex + 1;
			String val = txt.substring(startIndex + 1, endIndex);
			if (Tool.isNum(val)) {
				faceList.add(val);
				faceReplaceList.add("{" + val + "}");
			}
		}

		// 如果有表情符，先替换成%s，然后屏蔽字检查完之后，再还原表情符
		if (faceList.size() > 0) {
			try {
				List<Integer> indexList = new ArrayList<>();// 文本中包含的表情符,位置
				// 表情符替换成 ""
				for (int i = 0; i < faceList.size(); i++) {
					// 记录表情包的位置
					int indexOf = txt.indexOf(faceReplaceList.get(i));
					indexList.add(indexOf);// 这里记录是替换后文本的长度的位置
					String face = faceList.get(i);
					txt = txt.replaceFirst("\\{" + face + "\\}", "");
				}

				// 屏蔽词过滤
				logger.info("replace before txt = " + txt);
				txt = replaceSensitiveWord(txt, matchType, replaceChar);
				logger.info("replace after txt = " + txt);

				// 还原表情包的位置
				StringBuilder stringBuilder = new StringBuilder(txt);
				int replaceLengthTotal = 0;
				for (int i = 0; i < indexList.size(); i++) {
					Integer insertIndex = indexList.get(i);
					String key = faceReplaceList.get(i);
					stringBuilder.insert(replaceLengthTotal + insertIndex, key);
					replaceLengthTotal += key.length();
				}
				txt = stringBuilder.toString();
				logger.info("replace recover txt = " + txt);
			} catch (Exception e) {
				logger.error("replace error recover txt = " + txt);
				logger.error("replace error message = {} " + e.getMessage());
			}

		} else {
			txt = replaceSensitiveWord(txt, matchType, replaceChar);
		}
		return txt;
	}

	/**
	 * 替换敏感词内容
	 *
	 * @param replaceChar
	 * @param length
	 * @return
	 */
	private static String getReplaceChars(String replaceChar, int length) {
		String resultReplace = replaceChar;
		for (int i = 1; i < length; i++) {
			resultReplace += replaceChar;
		}

		return resultReplace;
	}

	/**
	 * 检查敏感词数量
	 *
	 * @param txt
	 * @param beginIndex
	 * @param matchType
	 * @return
	 */
	public static int checkSensitiveWord(String txt, int beginIndex, int matchType) {
		boolean flag = false;
		// 记录敏感词数量
		int matchFlag = 0;
		char word = 0;
		Map nowMap = SensitivewordEngine.sensitiveWordMap;
		for (int i = beginIndex; i < txt.length(); i++) {
			word = txt.charAt(i);
			// 判断该字是否存在于敏感词库中
			nowMap = (Map) nowMap.get(word);
			if (nowMap != null) {
				matchFlag++;
				// 判断是否是敏感词的结尾字，如果是结尾字则判断是否继续检测
				if ("1".equals(nowMap.get("isEnd"))) {
					flag = true;
					// 判断过滤类型，如果是小过滤则跳出循环，否则继续循环
					if (SensitivewordEngine.MinMatchType == matchType) {
						break;
					}
				}
			} else {
				break;
			}
		}
		if (!flag) {
			matchFlag = 0;
		}
		return matchFlag;
	}

	/**
	 * 验证用户名称是否正确
	 *
	 * @param userName 用户名称
	 * @return 错误码（0表示正确）
	 */
	public static ErrorWord checkUserName(String userName) {
		return checkUserName(userName, 4, 14, true);
	}

	/**
	 * 验证用户名称是否正确
	 *
	 * @param userName       用户名称
	 * @param lengthMin      最小长度
	 * @param lengthMax      最大长度
	 * @param checkSpaceChar 是否检查中间空格（一般true）
	 * @return 错误码（0表示正确）
	 */
	public static ErrorWord checkUserName(String userName, int lengthMin, int lengthMax, boolean checkSpaceChar) {
		int len = Tool.getStrByteLen(userName);
		if (len < lengthMin || len > lengthMax) {
			return ErrorWord.WORD_LENGTH_WRONG;//长度不符合规范
		}
		if (!Tool.checkFourByte(userName)) {
			return ErrorWord.CHAR_NOT_ALLOW;
		}
		// 正则\pP 其中的小写 p 是 property 的意思，表示 Unicode 属性，用于 Unicode 正表达式的前缀。
		// Unicode字符属性
		// P：标点字符
		// L：字母
		// M：标记符号（一般不会单独出现）
		// Z：分隔符（比如空格、换行等）
		// S：符号（比如数学符号、货币符号等）
		// N：数字（比如阿拉伯数字、罗马数字等）
		// C：其他字符
		boolean find;// 特殊字符检查
		if (checkSpaceChar) {
			// 通用标准检查
			find = Pattern.compile("[\\pP\\pS\\pZ\\pC]").matcher(userName).find();
		} else {
			// 不检查中间的空格（例如欧美地区）
			find = Pattern.compile("[\\pP\\pS\\pC]").matcher(userName).find() // 除了空格外的特殊字符部分
					|| Pattern.compile("(^\\s+)|(\\s+$)").matcher(userName).find()// 先检查首尾空格
					|| Pattern.compile("(?!\\s)\\pZ").matcher(userName).find();// 不检查中间普通空格，其它特殊空格还是要检查
		}
		if (find) {
			return ErrorWord.CHAR_NOT_ALLOW;
		}
		// null在敏感词库中过滤不掉，需要特殊处理
		if (userName.equalsIgnoreCase("null")) {
			return ErrorWord.BAD_WORD;
		}
		//先检查是否有敏感词
		if (SensitivewordEngine.isContaintSensitiveWord(userName, MinMatchType)) {
			return ErrorWord.BAD_WORD;
		}

		return ErrorWord.SUCCESS;
	}

	/**
	 * 检查文字
	 */
	public static String checkWord(String word, int maxLength) {
		// 超过最大长度自动截断
		if (word.length() > maxLength) {
			word = word.substring(0, maxLength);
		}
		// 过滤表情
//		word = Tool.dropFourByte(word);
		// 过滤敏感字符
		word = SensitivewordEngine.replaceSensitiveWord(word, SensitivewordEngine.MaxMatchType, "*");
		// 屏蔽# $符号
		word = Tool.replaceColorChar(word);
		return word;
	}

	/**
	 * 检查文字
	 */
	public static String checkWord(String word, int maxLength, int platform) throws Exception {
		// 超过最大长度自动截断
		if (word.length() > maxLength) {
			word = word.substring(0, maxLength);
		}
		// 过滤表情
//		word = Tool.dropFourByte(word);
		// 过滤敏感字符
		word = SensitivewordEngine.replaceWordBySdk(word, platform);
		// 屏蔽# $符号
		word = Tool.replaceColorChar(word);
		return word;
	}

	public static Future<String> replaceSensitiveWordOf4399(WebClient webClient, String toCheck) {

		Promise<String> future = Promise.promise();

		String url = "https://wo.webgame138.com/test/matchService.do";//请求地址
		String app = "ldt3";//请求appkey值
		String secret = "f6f7eec05cd39a1d06c6d030d1d04295";//秘钥
		String byPinyin = "true";//是否识别拼音
		//MD5加密处理获得sig
		String sig = Tool.md5encrypt32(secret + toCheck);
		try {
			//构造请求参数
			JsonObject params = new JsonObject();
			params.put("toCheck", URLEncoder.encode(toCheck, "UTF-8"));
			params.put("app", app);
			params.put("byPinyin", byPinyin);
			params.put("sig", sig);

			webClient.getAbs(url).timeout(3000).sendJsonObject(params, res -> {
				if (res.succeeded()) {
					System.out.println(res.result().bodyAsJsonObject());
					JsonObject object = res.result().bodyAsJsonObject();
					Iterator<Map.Entry<String, Object>> iter = object.iterator();
					//有匹配到敏感词,进行替换
					if (iter.hasNext()) {
						StringBuffer buffer = new StringBuffer(toCheck);
						for (; iter.hasNext(); ) {
							Map.Entry<String, Object> entry = iter.next();
							String key = entry.getKey();
							String[] split = key.split(":");
							int pos1 = Integer.parseInt(split[0]);
							int pos2 = Integer.parseInt(split[1]);
							String replaceChars = getReplaceChars("*", pos2 - pos1 + 1);
							buffer.replace(pos1, pos2 + 1, replaceChars).toString();
						}
//                        System.out.println("buffer : " + buffer.toString());
						future.complete(buffer.toString());
					}
				} else {
					//出现异常走自己敏感词库
					String s = replaceSensitiveWord(toCheck, SensitivewordEngine.MaxMatchType, "*");
					future.complete(s);
				}
			});

		} catch (IOException e) {
			//出现异常走自己敏感词库
			String s = replaceSensitiveWord(toCheck, SensitivewordEngine.MaxMatchType, "*");
			future.complete(s);
		}
		return future.future();
	}

	/**
	 * 校验客户端敏感词
	 *
	 * @param path 客户端导出的配置文件路径
	 */
	public static void checkClientName(String path) {
		try {
			logger.info("read file " + path);
			String content = FileUtils.getContentsAsString(new File(path));
			JsonObject jObj = new JsonObject(content);
			JsonObject errorMap = new JsonObject();
			for (String key : jObj.getMap().keySet()) {
				String val = jObj.getString(key);
				String test = replaceSensitiveWord(val, SensitivewordEngine.MaxMatchType, "*");
				if (!val.equals(test)) {
					errorMap.put(key, String.join("->", val, test));
				}
			}
			logger.info("result: {}", errorMap);
		} catch (IOException e) {
			logger.error(Tool.getException(e));
		}
	}
}